<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        // 属性描述符  用于描述一个属性的相关信息
        const obj = {
            name: "孙悟空",
            age: 500
        }

        Object.defineProperty(obj, "name", {
            // 设置值
            value: "唐僧",
            // 是否能写入
            writable: false,
            // 是否能遍历
            enumerable: false
        })
        obj.name = "沙和尚"//无法更改
        console.log(obj)
        // 无法遍历name
        for (const key in obj) {
            console.log(key);
        }

        // 在属性描述符中，使用了getter和setter中的任意一个，这个属性就不是一个普通的属性，就变成了一个存取器
        let Vue = {}

        Object.defineProperty(Vue, "name", {
            get() {
                console.log("有人来敲门")
                return "孙悟空"
            },
            set(value) {
                console.log(value, "========")
            }
        })

        console.log(Vue.name, Vue.title)//孙悟空 undefined
        Vue.name = "八戒"

        // 无法监听数组的变化
        let sun = {
            arr: [1, 2, 3]
        }
        Object.defineProperty(sun, "arr", {
            get() {
                console.log("数组访问了");
            },
            set(value) {
                console.log("数组修改了")
            }
        })
        // sun.arr.push(5) 无法监听 报错
        // sun.arr = [1] 直接覆盖数组 可以监听
        // sun.arr[0] = "八戒" 无法监听 报错
    </script>
</body>
</html>